package com.mjf.java.ai.langchain4j.tools;

import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import dev.langchain4j.agent.tool.ToolMemoryId;
import org.springframework.stereotype.Component;

/**
 * 用 `@Tool` 注解的方法：
 * <p>
 * - 既可以是静态的，也可以是非静态的；
 * - 可以具有任何可见性（公有、私有等）。
 * <p>
 * <p>
 * `@Tool` 注解有两个可选字段：
 * <p>
 * - name（工具名称）：工具的名称。如果未提供该字段，方法名会作为工具的名称。
 * - value（工具描述）：工具的描述信息。
 * <p>
 * 根据工具的不同，即使没有任何描述，大语言模型可能也能很好地理解它（例如，`add(a, b)` 就很直观），
 * 但通常最好提供清晰且有意义的名称和描述。
 * 这样，大语言模型就能获得更多信息，以决定是否调用给定的工具以及如何调用。
 */
@Component
public class CalculatorTools {

    /**
     * 方法参数可以选择使用 `@P` 注解进行标注。
     * <p>
     * `@P` 注解有两个字段：
     * <p>
     * - value：参数的描述信息，这是必填字段。
     * - required：表示该参数是否为必需项，默认值为 `true`，此为可选字段。
     */
    @Tool(name = "加法", value = "返回两个参数相加之和")
    double sum(
            @ToolMemoryId int memoryId,
            @P(value = "加数1", required = true) double a,
            @P(value = "加数2", required = true) double b
    ) {
        System.out.println("调用加法运算。 memoryId " + memoryId);
        return a + b;
    }

    @Tool(name = "平方根运算", value = "返回一个参数的平方根")
    double squareRoot(@ToolMemoryId int memoryId, double x) {
        System.out.println("调用平方根运算。 memoryId " + memoryId);
        return Math.sqrt(x);
    }
}
